{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-01-03T06:23:39.066349Z",
     "start_time": "2025-01-03T06:23:35.177128Z"
    }
   },
   "source": [
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "from sklearn.datasets import fetch_california_housing\n",
    "from sklearn.preprocessing import StandardScaler\n"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T06:37:31.101137Z",
     "start_time": "2025-01-03T06:37:31.070121Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 前面的代码执行的不错，但是它需要数学上通过损失函数MSE来求导梯度\n",
    "# 在线性回归的例子中，这样是可以的，看起来通过数学公式去求解不难\n",
    "# 但是如果是深度学习，我们很难这样去做，会比较头疼，会很容易出错\n",
    "# 幸运的是，TensorFlow提供的autodiff特性可以自动的并有效的计算梯度为我们\n",
    "# reverse-mode autodiff\n",
    "\n",
    "n_epochs = 10000\n",
    "learning_rate = 0.001\n",
    "\n",
    "housing = fetch_california_housing(data_home=\"./scikit_learn_data\", download_if_missing=True)\n",
    "\n",
    "m, n = housing.data.shape\n",
    "housing_data_plus_bias = np.c_[np.ones((m, 1)), housing.data]\n",
    "# 可以使用TensorFlow或者Numpy或者sklearn的StandardScaler去进行归一化\n",
    "scaler = StandardScaler().fit(housing_data_plus_bias)\n",
    "scaled_housing_data_plus_bias = scaler.transform(housing_data_plus_bias)\n",
    "\n",
    "X = tf.constant(scaled_housing_data_plus_bias, dtype=tf.float32, name='X')\n",
    "y = tf.constant(housing.target.reshape(-1, 1), dtype=tf.float32, name='y')\n"
   ],
   "id": "13f1bb2b19efbf07",
   "outputs": [],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T06:37:38.142793Z",
     "start_time": "2025-01-03T06:37:33.363930Z"
    }
   },
   "cell_type": "code",
   "source": [
    "\n",
    "# random_uniform函数创建图里一个节点包含随机数值，给定它的形状和取值范围，就像numpy里面rand()函数\n",
    "theta = tf.Variable(tf.random_uniform([n + 1, 1], -1.0, 1.0), name='theta')\n",
    "y_pred = tf.matmul(X, theta, name=\"predictions\")\n",
    "error = y_pred - y\n",
    "mse = tf.reduce_mean(tf.square(error), name=\"mse\")\n",
    "# 梯度的公式：(y_pred - y) * xj\n",
    "# gradients = 2/m * tf.matmul(tf.transpose(X), error)\n",
    "gradients = tf.gradients(mse, [theta])[0]\n",
    "# 赋值函数对于BGD来说就是 theta_new = theta - (learning_rate * gradients)\n",
    "training_op = tf.assign(theta, theta - learning_rate * gradients)\n",
    "\n",
    "init = tf.global_variables_initializer()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    sess.run(init)\n",
    "\n",
    "    for epoch in range(n_epochs):\n",
    "        if epoch % 100 == 0:\n",
    "            print(\"Epoch\", epoch, \"MSE = \", mse.eval())\n",
    "        sess.run(training_op)\n",
    "\n",
    "    best_theta = theta.eval()\n",
    "    print(best_theta)\n"
   ],
   "id": "13ee978ba5067e61",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From D:\\Documents\\Tool\\anaconda3\\envs\\tf-37\\lib\\site-packages\\tensorflow\\python\\framework\\op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n",
      "Epoch 0 MSE =  7.1323566\n",
      "Epoch 100 MSE =  6.157702\n",
      "Epoch 200 MSE =  5.6119094\n",
      "Epoch 300 MSE =  5.299617\n",
      "Epoch 400 MSE =  5.117249\n",
      "Epoch 500 MSE =  5.0087094\n",
      "Epoch 600 MSE =  4.942956\n",
      "Epoch 700 MSE =  4.9024477\n",
      "Epoch 800 MSE =  4.877074\n",
      "Epoch 900 MSE =  4.8609023\n",
      "Epoch 1000 MSE =  4.8503966\n",
      "Epoch 1100 MSE =  4.843416\n",
      "Epoch 1200 MSE =  4.838651\n",
      "Epoch 1300 MSE =  4.835294\n",
      "Epoch 1400 MSE =  4.8328385\n",
      "Epoch 1500 MSE =  4.8309684\n",
      "Epoch 1600 MSE =  4.829483\n",
      "Epoch 1700 MSE =  4.828253\n",
      "Epoch 1800 MSE =  4.8271956\n",
      "Epoch 1900 MSE =  4.826261\n",
      "Epoch 2000 MSE =  4.8254128\n",
      "Epoch 2100 MSE =  4.824629\n",
      "Epoch 2200 MSE =  4.823894\n",
      "Epoch 2300 MSE =  4.8231997\n",
      "Epoch 2400 MSE =  4.8225365\n",
      "Epoch 2500 MSE =  4.821903\n",
      "Epoch 2600 MSE =  4.8212943\n",
      "Epoch 2700 MSE =  4.820708\n",
      "Epoch 2800 MSE =  4.820143\n",
      "Epoch 2900 MSE =  4.8195972\n",
      "Epoch 3000 MSE =  4.819071\n",
      "Epoch 3100 MSE =  4.8185606\n",
      "Epoch 3200 MSE =  4.818068\n",
      "Epoch 3300 MSE =  4.8175917\n",
      "Epoch 3400 MSE =  4.81713\n",
      "Epoch 3500 MSE =  4.8166847\n",
      "Epoch 3600 MSE =  4.816253\n",
      "Epoch 3700 MSE =  4.8158345\n",
      "Epoch 3800 MSE =  4.815431\n",
      "Epoch 3900 MSE =  4.815039\n",
      "Epoch 4000 MSE =  4.814662\n",
      "Epoch 4100 MSE =  4.8142943\n",
      "Epoch 4200 MSE =  4.8139405\n",
      "Epoch 4300 MSE =  4.8135967\n",
      "Epoch 4400 MSE =  4.8132644\n",
      "Epoch 4500 MSE =  4.8129435\n",
      "Epoch 4600 MSE =  4.8126316\n",
      "Epoch 4700 MSE =  4.812331\n",
      "Epoch 4800 MSE =  4.8120394\n",
      "Epoch 4900 MSE =  4.811757\n",
      "Epoch 5000 MSE =  4.811484\n",
      "Epoch 5100 MSE =  4.8112197\n",
      "Epoch 5200 MSE =  4.810964\n",
      "Epoch 5300 MSE =  4.8107166\n",
      "Epoch 5400 MSE =  4.8104773\n",
      "Epoch 5500 MSE =  4.810244\n",
      "Epoch 5600 MSE =  4.8100195\n",
      "Epoch 5700 MSE =  4.8098025\n",
      "Epoch 5800 MSE =  4.8095927\n",
      "Epoch 5900 MSE =  4.8093886\n",
      "Epoch 6000 MSE =  4.8091917\n",
      "Epoch 6100 MSE =  4.8090005\n",
      "Epoch 6200 MSE =  4.808817\n",
      "Epoch 6300 MSE =  4.808637\n",
      "Epoch 6400 MSE =  4.8084655\n",
      "Epoch 6500 MSE =  4.8082976\n",
      "Epoch 6600 MSE =  4.808136\n",
      "Epoch 6700 MSE =  4.8079796\n",
      "Epoch 6800 MSE =  4.8078275\n",
      "Epoch 6900 MSE =  4.8076806\n",
      "Epoch 7000 MSE =  4.8075376\n",
      "Epoch 7100 MSE =  4.8074\n",
      "Epoch 7200 MSE =  4.8072677\n",
      "Epoch 7300 MSE =  4.807139\n",
      "Epoch 7400 MSE =  4.807014\n",
      "Epoch 7500 MSE =  4.806893\n",
      "Epoch 7600 MSE =  4.806777\n",
      "Epoch 7700 MSE =  4.8066626\n",
      "Epoch 7800 MSE =  4.8065534\n",
      "Epoch 7900 MSE =  4.8064475\n",
      "Epoch 8000 MSE =  4.806345\n",
      "Epoch 8100 MSE =  4.8062453\n",
      "Epoch 8200 MSE =  4.8061495\n",
      "Epoch 8300 MSE =  4.806057\n",
      "Epoch 8400 MSE =  4.8059664\n",
      "Epoch 8500 MSE =  4.80588\n",
      "Epoch 8600 MSE =  4.805795\n",
      "Epoch 8700 MSE =  4.805714\n",
      "Epoch 8800 MSE =  4.8056345\n",
      "Epoch 8900 MSE =  4.8055587\n",
      "Epoch 9000 MSE =  4.8054843\n",
      "Epoch 9100 MSE =  4.8054123\n",
      "Epoch 9200 MSE =  4.805343\n",
      "Epoch 9300 MSE =  4.8052754\n",
      "Epoch 9400 MSE =  4.8052106\n",
      "Epoch 9500 MSE =  4.8051486\n",
      "Epoch 9600 MSE =  4.805087\n",
      "Epoch 9700 MSE =  4.805028\n",
      "Epoch 9800 MSE =  4.8049717\n",
      "Epoch 9900 MSE =  4.804916\n",
      "[[-2.8540277e-01]\n",
      " [ 8.0552787e-01]\n",
      " [ 1.3006990e-01]\n",
      " [-1.9039212e-01]\n",
      " [ 2.3054102e-01]\n",
      " [-7.2957468e-05]\n",
      " [-3.9770074e-02]\n",
      " [-8.4000045e-01]\n",
      " [-8.0641913e-01]]\n"
     ]
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "f77840fe6dbeb410"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
